
#include "Intersection.h"


#ifndef UTILS_TRIANGLE
#define UTILS_TRIANGLE

class Triangle2D {
public:
    Vector2f v0, v1, v2;
    Vector2f t0, t1, t2;
    std::shared_ptr<Material> material;

    Triangle2D(
        const std::shared_ptr<Material>& _material
    ) : v0(ZeroVector3f), v1(ZeroVector3f), v2(ZeroVector3f),
        t0(ZeroVector2f), t1(ZeroVector2f), t2(ZeroVector2f),
        material(_material) {}
    
    Triangle2D(
        const Vector2f& _v0, const Vector2f& _v1, const Vector2f& _v2,
        const std::shared_ptr<Material>& _material
    ) : v0(_v0), v1(_v1), v2(_v2),
        t0(ZeroVector2f), t1(ZeroVector2f), t2(ZeroVector2f),
        material(_material) {}

    Triangle2D(
        const Vector2f& _v0, const Vector2f& _v1, const Vector2f& _v2,
        const Vector2f& _t0, const Vector2f& _t1, const Vector2f& _t2,
        const std::shared_ptr<Material>& _material
    ) : v0(_v0), v1(_v1), v2(_v2),
        t0(_t0), t1(_t1), t2(_t2),
        material(_material) {}
};

class Triangle3D {
public:
    Vector3f v0, v1, v2;
    Vector3f n0, n1, n2;
    Vector2f t0, t1, t2;
    std::shared_ptr<Material> material;

    Triangle3D(
        const std::shared_ptr<Material>& _material
    ) : v0(ZeroVector3f), v1(ZeroVector3f), v2(ZeroVector3f),
        n0(ZeroVector3f), n1(ZeroVector3f), n2(ZeroVector3f),
        t0(ZeroVector2f), t1(ZeroVector2f), t2(ZeroVector2f),
        material(_material) {}

    Triangle3D(
        const Vector3f& _v0, const Vector3f& _v1, const Vector3f& _v2,
        const std::shared_ptr<Material>& _material
    ) : v0(_v0), v1(_v1), v2(_v2),
        n0(ZeroVector3f), n1(ZeroVector3f), n2(ZeroVector3f),
        t0(ZeroVector2f), t1(ZeroVector2f), t2(ZeroVector2f),
        material(_material) {}

    Triangle3D(
        const Vector3f& _v0, const Vector3f& _v1, const Vector3f& _v2,
        const Vector3f& _n0, const Vector3f& _n1, const Vector3f& _n2,
        const std::shared_ptr<Material>& _material
    ) : v0(_v0), v1(_v1), v2(_v2),
        n0(_n0), n1(_n1), n2(_n2),
        t0(ZeroVector2f), t1(ZeroVector2f), t2(ZeroVector2f),
        material(_material) {}

    Triangle3D(
        const Vector3f& _v0, const Vector3f& _v1, const Vector3f& _v2,
        const Vector3f& _n,
        const std::shared_ptr<Material>& _material
    ) : v0(_v0), v1(_v1), v2(_v2),
        n0(_n), n1(_n), n2(_n),
        t0(ZeroVector2f), t1(ZeroVector2f), t2(ZeroVector2f),
        material(_material) {}

    Triangle3D(
        const Vector3f& _v0, const Vector3f& _v1, const Vector3f& _v2,
        const Vector3f& _n0, const Vector3f& _n1, const Vector3f& _n2,
        const Vector2f& _t0, const Vector2f& _t1, const Vector2f& _t2,
        const std::shared_ptr<Material>& _material
    ) : v0(_v0), v1(_v1), v2(_v2),
        n0(_n0), n1(_n1), n2(_n2),
        t0(_t0), t1(_t1), t2(_t2),
        material(_material) {}

    Triangle3D(
        const Vector3f& _v0, const Vector3f& _v1, const Vector3f& _v2,
        const Vector3f& _n,
        const Vector2f& _t0, const Vector2f& _t1, const Vector2f& _t2,
        const std::shared_ptr<Material>& _material
    ) : v0(_v0), v1(_v1), v2(_v2),
        n0(_n), n1(_n), n2(_n),
        t0(_t0), t1(_t1), t2(_t2),
        material(_material) {}
    
    Bounds3f getBounds() const {
        return Bounds3f(MinEachComponent(v0, v1, v2), MaxEachComponent(v0, v1, v2));
    }
};

#endif // UTILS_TRIANGLE
